package home.mutant.gauto.generative;

import java.util.ArrayList;
import java.util.List;

import jenes.GeneticAlgorithm;
import jenes.algorithms.SimpleGA;
import jenes.chromosome.BitwiseChromosome;
import jenes.population.Individual;
import jenes.population.Population;
import jenes.tutorials.utils.Utils;
import jenes.utils.multitasking.MultiThreadEvaluator;
import home.mutant.gauto.ui.ResultFrame;

public class Main
{
	public static void main(String[] args) throws Exception
	{
		mainBitChromosome();
	}

	private static void mainDoubleChromosome() throws Exception
	{
/*		ResultFrame frame = new ResultFrame(1200, 600);
		List<Integer> neurons = new ArrayList<Integer>();
		neurons.add(3);
		neurons.add(100);
        Individual<DoubleChromosome> sample = new Individual<DoubleChromosome>(new DoubleChromosome(WeightsModel.getChromosomeLengthNoBias(neurons),-30,30));
        Population<DoubleChromosome> pop = new Population<DoubleChromosome>(sample, 100);
        GenerativeFitness fitness = new GenerativeFitness(neurons,1);
		SimpleGA<DoubleChromosome> ga = new SimpleGA<DoubleChromosome>(fitness, pop);
        ga.setGenerationLimit(30);
        //ga.evolve();
        
        Individual solution=null;
        MultiThreadEvaluator eval = new MultiThreadEvaluator(4);
        for (int i = 0;i<100;i++)
        {
        	eval.execute(ga,false);
        	System.out.println("################ Generation "+(i+1)*30+" ######################");
        	solution = printStatistics(ga);
        	frame.showIndividual(neurons,solution);
        }	*/	
	}
	
	private static void mainBitChromosome() throws Exception
	{
		ResultFrame frame = new ResultFrame(1200, 600);
		List<Integer> neurons = new ArrayList<Integer>();
		neurons.add(8);
		neurons.add(100);
        Individual<BitwiseChromosome> sample = new Individual<BitwiseChromosome>(new BitwiseChromosome(WeightsModel.getChromosomeLengthNoBias(neurons),new SignedShortCoding()));
        int initPopulation = 5000;
        Population<BitwiseChromosome> pop = new Population<BitwiseChromosome>(sample, initPopulation);
        GenerativeFitness fitness = new GenerativeFitness(neurons);
		SimpleGA<BitwiseChromosome> ga = new SimpleGA<BitwiseChromosome>(fitness, pop);
        ga.setGenerationLimit(10);
        ga.setMutationProbability(0.2);
        Individual solution=null;
        MultiThreadEvaluator eval = new MultiThreadEvaluator(4);
        for (int i = 0;i<200;i++)
        {
       		eval.execute(ga,false);
       		//ga.setMutationProbability(0.02-i*0.02);
        	System.out.println("################ Generation "+(i+1)*10+" ######################");
        	solution = printStatistics(ga);
        	frame.showIndividual(neurons,solution);
        	Population<BitwiseChromosome> currentPopulation = ga.getCurrentPopulation();
        	currentPopulation.resize(initPopulation+(i+1)*20);
			ga = new SimpleGA<BitwiseChromosome>(fitness, currentPopulation);
            ga.setGenerationLimit(10);
            ga.setMutationProbability(0.2);
            ga.setRandomization(false);
        }		
	}
	
	private static Individual printStatistics(SimpleGA<BitwiseChromosome> ga)
	{
		Population.Statistics stats = ga.getCurrentPopulation().getStatistics();
        GeneticAlgorithm.Statistics algostats = ga.getStatistics();
        Individual solution = stats.getLegalHighestIndividual();
        System.out.print("Solution: ");
        System.out.print( solution.getScore() );
        System.out.format(" found in %d ms.\n", algostats.getExecutionTime() );
        
        //Utils.printStatistics(stats);
		return solution;
	}
	
}